package com.phaeton.beemeup.entity;

import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.entity.shape.IShape;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.input.touch.TouchEvent;

import android.util.Log;

import com.phaeton.beemeup.GameManager;
import com.phaeton.beemeup.constants.SceneConstants;

public class Fight extends AnimatedSprite{
	CopyOnWriteArrayList<UUID> fightingBees = new CopyOnWriteArrayList<UUID>();
	CopyOnWriteArrayList<UUID> fightingWasps = new CopyOnWriteArrayList<UUID>();
	float x;
	float y;
	private TimerHandler fightHandler;
	private GameManager mGameManager;
	private IShape arena;
	private FightProgress progress;
	private int beeHealth;
	private int waspHealth;
	
	public Fight(float x, float y, final GameManager pGameManager) {
		
		super(x, y, pGameManager.getActivity().getSceneManager().getTiledTexture("Fight"), pGameManager.getActivity().getVertexBufferObjectManager());
		this.x = x;
		this.y = y;
		this.mGameManager = pGameManager;		
		
		progress = new FightProgress(pGameManager, x, y, 0);
		pGameManager.getLevel().getChildByIndex(SceneConstants.LAYER_GUI).attachChild(progress);
		
		fightHandler = new TimerHandler(1.5f, true, new ITimerCallback() {
			@Override
			public void onTimePassed(TimerHandler pTimerHandler) {	
				beeHealth -= fightingWasps.size() * 20;
				waspHealth -= fightingBees.size() * 20;

				Log.e("Fight", "in fight with " + beeHealth + " : " + waspHealth);
				
				progress.setProgress((float)beeHealth/(float)(beeHealth + waspHealth));
				
				if(getScore() != 0) {
					for(UUID bee: fightingBees) {
//						fightingBees.remove(bee);
						if(pGameManager.getBees().get(bee) != null) pGameManager.getBees().get(bee).removeState(IInsect.FIGHT);
					}
					for(UUID wasp: fightingWasps) {
//						fightingWasps.remove(wasp);
						if(pGameManager.getWasps().get(wasp) != null) pGameManager.getWasps().get(wasp).removeState(IInsect.FIGHT);
					}
					stopFight();
				}
			}			
		});
	}
	
	public void startFight(){
		Log.e("Fight", "start fight with " + fightingBees.size() + " bees and " + fightingWasps.size() + " wasps");
		this.animate(100);
		mGameManager.getLevel().registerUpdateHandler(fightHandler);		
		
		if(arena != null){
			if(arena instanceof BeeComb || arena instanceof WaspComb){
				((Comb) arena).deOccupy();
			}
			if(arena instanceof Flower){
				((Flower) arena).deOccupy();
			}
		}
	}
	
	public void stopFight(){		
		Log.e("Fight", "stopped fith with score "+getScore()+ " and " + fightingBees.size() + " bees and "+fightingWasps.size()+" wasps");
		mGameManager.getLevel().unregisterUpdateHandler(fightHandler);
		fightHandler.reset();
		mGameManager.removeFight(Fight.this);
		
		if(beeHealth > 0){
			for(int i = 0; i < beeHealth; i += 100){
				if(fightingBees.size() > 0){
					mGameManager.getLevel().getChildByIndex(SceneConstants.LAYER_BEES).attachChild(mGameManager.getBees().get(fightingBees.get(fightingBees.size() - 1)));
					mGameManager.getBees().get(fightingBees.get(fightingBees.size() - 1)).injure();
					fightingBees.remove(fightingBees.get(fightingBees.size() - 1));
				}
			}
		}
		
		if(waspHealth > 0){
			for(int i = 0; i < waspHealth; i += 100){
				if(fightingWasps.size() > 0){
					mGameManager.getLevel().getChildByIndex(SceneConstants.LAYER_BEES).attachChild(mGameManager.getWasps().get(fightingWasps.get(fightingWasps.size() - 1)));
					mGameManager.getWasps().get(fightingWasps.get(fightingWasps.size() - 1)).injure();
					fightingWasps.remove(fightingWasps.get(fightingWasps.size() - 1));
				}
			}
		}

		for(UUID bee: fightingBees) {
			Fight.this.removeBee(bee);
			mGameManager.getBees().get(bee).removeState(IInsect.FIGHT);
	
			mGameManager.destroyBee(bee);
		}

		for(UUID wasp: fightingWasps) {
			Fight.this.removeWasp(wasp);
			mGameManager.getWasps().get(wasp).removeState(IInsect.FIGHT);
	
			mGameManager.destroyWasp(wasp);
		}
		
		progress.detachSelf();
				
		if(arena != null){
			if(arena instanceof BeeComb || arena instanceof WaspComb){
				((Comb) arena).removeState(Comb.FIGHT);
				Log.e("Fight", "arena state "+((Comb) arena).getState());
			}
			if(arena instanceof Flower){
				((Flower) arena).removeState(Flower.FIGHT);
				Log.e("Fight", "arena state "+((Flower) arena).getState());
			}
		}
	}
	
	public synchronized void addBee(final UUID bee) {
		mGameManager.getActivity().runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
				mGameManager.getBees().get(bee).detachSelf();
			}
		});
		fightingBees.add(bee);
		mGameManager.getBees().get(bee).addState(IInsect.FIGHT);
		mGameManager.getBees().get(bee).setHoney(0);
		
		if(arena == null){
			for(BeeComb comb: mGameManager.getBeeCombs().values()){
				if(comb.getOccupant() != null && comb.getOccupant().equals(mGameManager.getBees().get(bee))){
					comb.addState(Comb.FIGHT);
					arena = comb;
					Log.e("Fight", "arena "+comb);
				}					
			}
			for(Flower flower: mGameManager.getFlowers().values()){
				if(flower.getOccupant() != null && flower.getOccupant().equals(mGameManager.getBees().get(bee))){
					flower.addState(Flower.FIGHT);
					arena = flower;
					Log.e("Fight", "arena "+flower);
				}					
			}
		}
		
		beeHealth += Bee.MAX_HEALTH;
	}
	
	public synchronized void addWasp(final UUID wasp) {
		mGameManager.getActivity().runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
				Log.e("Fight", "detaching...");
				mGameManager.getWasps().get(wasp).detachSelf();
			}
		});
		fightingWasps.add(wasp);
		mGameManager.getWasps().get(wasp).addState(IInsect.FIGHT);
		mGameManager.getWasps().get(wasp).setMaterial(0);
		
		if(arena == null){
			for(WaspComb comb: mGameManager.getWaspCombs().values()){
				if(comb.getOccupant() != null && comb.getOccupant().equals(mGameManager.getWasps().get(wasp))){
					comb.addState(Comb.FIGHT);
					arena = comb;
					Log.e("Fight", "occupied comb "+comb);
				}					
			}
			for(Flower flower: mGameManager.getFlowers().values()){
				if(flower.getOccupant() != null && flower.getOccupant().equals(mGameManager.getWasps().get(wasp))){
					flower.addState(Flower.FIGHT);
					arena = flower;
					Log.e("Fight", "occupied flower "+flower);
				}					
			}
		}
		
		waspHealth += Wasp.MAX_HEALTH;
	}
	
	public synchronized void removeBee(UUID bee) {
		fightingBees.remove(bee);
	}
	
	public synchronized void removeWasp(UUID wasp) {
		fightingWasps.remove(wasp);
	}
	
	public int getScore() {
		if(beeHealth <= 0) {
			return -1;
		}
		if(waspHealth <= 0) {
			return 1;
		}
		
		return 0;
	}
	
	public CopyOnWriteArrayList<UUID> getFightingBees() {
		return fightingBees;
	}

	public CopyOnWriteArrayList<UUID> getFightingWasps() {
		return fightingWasps;
	}

	public float getX() {
		return x;
	}
	
	public float getY() {
		return y;
	}
	
	@Override
	public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY){
		if(mGameManager.getSelectedBee() != null){
			mGameManager.getBees().get(mGameManager.getSelectedBee()).setTarget(this);
			mGameManager.getBees().get(mGameManager.getSelectedBee()).fly();
			return true;
		}
		return false;
	}
	
}
